package studio.baka.satoripixeldungeon.levels.rooms.special;

import studio.baka.satoripixeldungeon.Challenges;
import studio.baka.satoripixeldungeon.Dungeon;
import studio.baka.satoripixeldungeon.items.Generator;
import studio.baka.satoripixeldungeon.items.Heap;
import studio.baka.satoripixeldungeon.items.Item;
import studio.baka.satoripixeldungeon.items.potions.PotionOfLevitation;
import studio.baka.satoripixeldungeon.levels.Level;
import studio.baka.satoripixeldungeon.levels.Terrain;
import studio.baka.satoripixeldungeon.levels.painters.Painter;
import studio.baka.satoripixeldungeon.levels.traps.*;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import com.watabou.utils.Reflection;

import java.util.Objects;

public class TrapsRoom extends SpecialRoom {

    public void paint(Level level) {

        Painter.fill(level, this, Terrain.WALL);

        Class<? extends Trap> trapClass;
        if (Random.Int(4) == 0) {
            trapClass = null;
        } else {
            trapClass = Random.oneOf(levelTraps[Dungeon.depth / 5]);
        }

        if (trapClass == null) {
            Painter.fill(level, this, 1, Terrain.CHASM);
        } else {
            Painter.fill(level, this, 1, Terrain.TRAP);
        }

        Door door = entrance();
        door.set(Door.Type.REGULAR);

        int lastRow = level.map[left + 1 + (top + 1) * level.width()] == Terrain.CHASM ? Terrain.CHASM : Terrain.EMPTY;

        int x = -1;
        int y = -1;
        if (door.x == left) {
            x = right - 1;
            y = top + height() / 2;
            Painter.fill(level, x, top + 1, 1, height() - 2, lastRow);
        } else if (door.x == right) {
            x = left + 1;
            y = top + height() / 2;
            Painter.fill(level, x, top + 1, 1, height() - 2, lastRow);
        } else if (door.y == top) {
            x = left + width() / 2;
            y = bottom - 1;
            Painter.fill(level, left + 1, y, width() - 2, 1, lastRow);
        } else if (door.y == bottom) {
            x = left + width() / 2;
            y = top + 1;
            Painter.fill(level, left + 1, y, width() - 2, 1, lastRow);
        }

        for (Point p : getPoints()) {
            int cell = level.pointToCell(p);
            if (level.map[cell] == Terrain.TRAP) {
                level.setTrap(Objects.requireNonNull(Reflection.newInstance(trapClass)).reveal(), cell);
            }
        }

        int pos = x + y * level.width();
        if (Random.Int(3) == 0) {
            if (lastRow == Terrain.CHASM) {
                Painter.set(level, pos, Terrain.EMPTY);
            }
            level.drop(prize(level), pos).type = Heap.Type.CHEST;
        } else {
            Painter.set(level, pos, Terrain.PEDESTAL);
            level.drop(prize(level), pos);
        }

        level.addItemToSpawn(new PotionOfLevitation());
    }

    private static Item prize(Level level) {

        Item prize;

        if (Random.Int(3) != 0) {
            prize = level.findPrizeItem();
            if (prize != null)
                return prize;
        }

        //1 floor set higher in probability, never cursed
        do {
            if (Random.Int(2) == 0) {
                prize = Generator.randomWeapon((Dungeon.depth / 5) + 1);
            } else {
                prize = Generator.randomArmor((Dungeon.depth / 5) + 1);
            }
        } while (prize.cursed || Challenges.isItemBlocked(prize));
        prize.cursedKnown = true;

        //33% chance for an extra update.
        if (Random.Int(3) == 0) {
            prize.upgrade();
        }

        return prize;
    }

    @SuppressWarnings("unchecked")
    private static final Class<? extends Trap>[][] levelTraps = new Class[][]{
            //sewers
            {GrippingTrap.class, TeleportationTrap.class, FlockTrap.class},
            //prison
            {PoisonDartTrap.class, GrippingTrap.class, ExplosiveTrap.class},
            //caves
            {PoisonDartTrap.class, FlashingTrap.class, ExplosiveTrap.class},
            //city
            {WarpingTrap.class, FlashingTrap.class, DisintegrationTrap.class},
            //halls, muahahahaha
            {GrimTrap.class},
            //hallow
            {GrimTrap.class}
    };
}
